package com.service.Impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.common.Constant;
import com.entity.SharesDataProbRed;
import com.mapper.SharesDataProbRedMapper;
import com.service.SharesDataProbRedService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author pumpkin
 * @since 2021-03-26
 */
@Service
public class SharesDataProbRedServiceImpl extends ServiceImpl<SharesDataProbRedMapper, SharesDataProbRed> implements SharesDataProbRedService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void getPorbByCodeAndTrend(SharesDataProbRed sharesDataProbRed) {
        String zdfTrend = sharesDataProbRed.getZdfTrend();
        if(zdfTrend.contains("-")||zdfTrend.contains("+")){
            //查询单支3-7天的概率
            this.getPorbSingle(sharesDataProbRed);//5
            //查询板块5-7天的概率
            this.getPorbPlate(sharesDataProbRed);//5
            //查询全部5-7天的概率
            this.getPorbAll(sharesDataProbRed);//5
            //查询zdf板块3-5天的概率
//            this.getZdfProbPlate(sharesDataProbRed);//5

            //查询明天跌，后天单支3-7天的概率
            this.getAfterPorbSingle(sharesDataProbRed);//5
            //查询明天跌，后天板块5-7天的概率
            this.getAfterPorbPlate(sharesDataProbRed);//5
            //查询明天跌，后天全部5-7天的概率
            this.getAfterPorbAll(sharesDataProbRed);//5
            //查询明天跌，后天zdf板块3-5天的概率
//            this.getAfterZdfProbPlate(sharesDataProbRed);//5
        }else{
            //查询单支3-7天的概率
//            this.getPorbSingle(sharesDataProbRed);//5
            //查询板块5-7天的概率
            this.getPorbPlate(sharesDataProbRed);//5
            //查询全部5-7天的概率
            this.getPorbAll(sharesDataProbRed);//5
            //查询zdf板块3-5天的概率
            this.getZdfProbPlate(sharesDataProbRed);//5

            //查询明天跌，后天单支3-7天的概率
            this.getAfterPorbSingle(sharesDataProbRed);//5
            //查询明天跌，后天板块5-7天的概率
            this.getAfterPorbPlate(sharesDataProbRed);//5
            //查询明天跌，后天全部5-7天的概率
            this.getAfterPorbAll(sharesDataProbRed);//5
        }
    }
    /**
     * 查询单支3-7天的概率
     * @param sharesDataProbRed
     */
    @Override
    public void getPorbSingle(SharesDataProbRed sharesDataProbRed) {

        String code = sharesDataProbRed.getCode();
        String zdfTrend = sharesDataProbRed.getZdfTrend().replaceAll("\\d+", "");;

        //7天
        Integer add7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend+"+");
        Integer sub7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend+"-");
        double d7=getEndNum(add7,sub7);
        if(0!=d7){
            sharesDataProbRed.setProbSeven(d7);
        }
        sharesDataProbRed.setProbSevenAdd(add7);
        sharesDataProbRed.setProbSevenSub(sub7);


        //6天
        Integer add6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"+");
        Integer sub6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"-");
        double d6=getEndNum(add6,sub6);
        if(0!=d6){
            sharesDataProbRed.setProbSix(d6);
        }
        sharesDataProbRed.setProbSixAdd(add6);
        sharesDataProbRed.setProbSixSub(sub6);

        //5天
        Integer add5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"+");
        Integer sub5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"-");
        double d5=getEndNum(add5,sub5);
        if(0!=d5){
            sharesDataProbRed.setProbFive(d5);
        }
        sharesDataProbRed.setProbFiveAdd(add5);
        sharesDataProbRed.setProbFiveSub(sub5);

        //4天
        Integer add4 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(3)+"+");
        Integer sub4 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(3)+"-");
        double d4=getEndNum(add4,sub4);
        if(0!=d4){
            sharesDataProbRed.setProbFour(d4);
        }
        sharesDataProbRed.setProbFourAdd(add4);
        sharesDataProbRed.setProbFourSub(sub4);

        //3天
        Integer add3 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(4)+"+");
        Integer sub3 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(4)+"-");
        double d3=getEndNum(add3,sub3);
        if(0!=d3){
            sharesDataProbRed.setProbThree(d3);
        }
        sharesDataProbRed.setProbThreeAdd(add3);
        sharesDataProbRed.setProbThreeSub(sub3);

    }

    @Override
    public void getPorbPlate(SharesDataProbRed sharesDataProbRed) {
        String code = sharesDataProbRed.getCode().substring(0,3);
        String zdfTrend = sharesDataProbRed.getZdfTrend().replaceAll("\\d+", "");;

        //7天
        Integer add7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend+"+");
        Integer sub7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend+"-");
        double d7=getEndNum(add7,sub7);
        if(0!=d7){
            sharesDataProbRed.setProbSevenPlate(d7);
        }
        sharesDataProbRed.setProbSevenPlateAdd(add7);
        sharesDataProbRed.setProbSevenPlateSub(sub7);

        //6天

        Integer add6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"+");
        Integer sub6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"-");
        double d6=getEndNum(add6,sub6);
        if(0!=d6){
            sharesDataProbRed.setProbSixPlate(d6);
        }
        sharesDataProbRed.setProbSixPlateAdd(add6);
        sharesDataProbRed.setProbSixPlateSub(sub6);

        //5天
        Integer add5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"+");
        Integer sub5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"-");
        double d5=getEndNum(add5,sub5);
        if(0!=d5){
            sharesDataProbRed.setProbFivePlate(d5);
        }
        sharesDataProbRed.setProbFivePlateAdd(add5);
        sharesDataProbRed.setProbFivePlateSub(sub5);

    }

    @Override
    public void getPorbAll(SharesDataProbRed sharesDataProbRed) {
        String code = Constant.ALL;
        String zdfTrend = sharesDataProbRed.getZdfTrend().replaceAll("\\d+", "");;

        //7天
        Integer add7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend+"+");
        Integer sub7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend+"-");
        double d7=getEndNum(add7,sub7);
        if(0!=d7){
            sharesDataProbRed.setProbSevenAll(d7);
        }
        sharesDataProbRed.setProbSevenAllAdd(add7);
        sharesDataProbRed.setProbSevenAllSub(sub7);


        //6天

        Integer add6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"+");
        Integer sub6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"-");
        double d6=getEndNum(add6,sub6);
        if(0!=d6){
            sharesDataProbRed.setProbSixAll(d6);
        }
        sharesDataProbRed.setProbSixAllAdd(add6);
        sharesDataProbRed.setProbSixAllSub(sub6);

        //5天
        Integer add5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"+");
        Integer sub5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"-");
        double d5=getEndNum(add5,sub5);
        if(0!=d5){
            sharesDataProbRed.setProbFiveAll(d5);
        }
        sharesDataProbRed.setProbFiveAllAdd(add5);
        sharesDataProbRed.setProbFiveAllSub(sub5);
    }


    @Override
    public void getZdfProbPlate(SharesDataProbRed sharesDataProbRed) {
        String zdfTrend = sharesDataProbRed.getZdfTrend();
        Map<String, Double> zdf5 = getZdfProbAllByRedis(sharesDataProbRed, zdfTrend.substring(4));
        Double p5 = zdf5.get(Constant.ALL);
        Integer add5 = zdf5.get("add").intValue();
        Integer sub5 = zdf5.get("div").intValue();
        if(0!=p5){
            sharesDataProbRed.setZdfProbFivePlate(p5);
        }
        sharesDataProbRed.setZdfProbFivePlateAdd(add5);
        sharesDataProbRed.setZdfProbFivePlateSub(sub5);

        Map<String, Double> zdf4 = getZdfProbAllByRedis(sharesDataProbRed, zdfTrend.substring(8));
        Integer add4 = zdf4.get("add").intValue();
        Integer sub4 = zdf4.get("div").intValue();
        Double p4 = zdf4.get(Constant.ALL);
        if(0!=p4){
            sharesDataProbRed.setZdfProbFourPlate(p4);
        }
        sharesDataProbRed.setZdfProbFourPlateAdd(add4);
        sharesDataProbRed.setZdfProbFourPlateSub(sub4);

        Map<String, Double> zdf3 = getZdfProbAllByRedis(sharesDataProbRed, zdfTrend.substring(10));
        Integer add3 = zdf3.get("add").intValue();
        Integer sub3 = zdf3.get("div").intValue();
        Double p3 = zdf3.get(Constant.ALL);
        if(0!=p3){
            sharesDataProbRed.setZdfProbThreePlate(p3);
        }
        sharesDataProbRed.setZdfProbThreePlateAdd(add3);
        sharesDataProbRed.setZdfProbThreePlateSub(sub3);
    }

    @Override
    public void getAfterPorbSingle(SharesDataProbRed sharesDataProbRed) {
        String code = sharesDataProbRed.getCode();
        String zdfTrend = sharesDataProbRed.getZdfTrend().replaceAll("\\d+", "")+"-";

        //7天
        Integer add7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"+");
        Integer sub7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"-");
        double d7=getEndNum(add7,sub7);
        if(0!=d7){
            sharesDataProbRed.setProbSevenGreen(d7);
        }
        sharesDataProbRed.setProbSevenGreenAdd(add7);
        sharesDataProbRed.setProbSevenGreenSub(sub7);


        //6天
        Integer add6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"+");
        Integer sub6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"-");
        double d6=getEndNum(add6,sub6);
        if(0!=d6){
            sharesDataProbRed.setProbSixGreen(d6);
        }
        sharesDataProbRed.setProbSixGreenAdd(add6);
        sharesDataProbRed.setProbSixGreenSub(sub6);

        //5天
        Integer add5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(3)+"+");
        Integer sub5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(3)+"-");
        double d5=getEndNum(add5,sub5);
        if(0!=d5){
            sharesDataProbRed.setProbFiveGreen(d5);
        }
        sharesDataProbRed.setProbFiveGreenAdd(add5);
        sharesDataProbRed.setProbFiveGreenSub(sub5);

        //4天
        Integer add4 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(4)+"+");
        Integer sub4 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(4)+"-");
        double d4=getEndNum(add4,sub4);
        if(0!=d4){
            sharesDataProbRed.setProbFourGreen(d4);
        }
        sharesDataProbRed.setProbFourGreenAdd(add4);
        sharesDataProbRed.setProbFourGreenSub(sub4);

        //3天
        Integer add3 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(5)+"+");
        Integer sub3 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(5)+"-");
        double d3=getEndNum(add3,sub3);
        if(0!=d3){
            sharesDataProbRed.setProbThreeGreen(d3);
        }
        sharesDataProbRed.setProbThreeGreenAdd(add3);
        sharesDataProbRed.setProbThreeGreenSub(sub3);

    }

    @Override
    public void getAfterPorbPlate(SharesDataProbRed sharesDataProbRed) {
        String code = sharesDataProbRed.getCode().substring(0,3);
        String zdfTrend = sharesDataProbRed.getZdfTrend().replaceAll("\\d+", "")+"-";

        //7天
        Integer add7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"+");
        Integer sub7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"-");
        double d7=getEndNum(add7,sub7);
        if(0!=d7){
            sharesDataProbRed.setProbSevenPlateGreen(d7);
        }
        sharesDataProbRed.setProbSevenPlateGreenAdd(add7);
        sharesDataProbRed.setProbSevenPlateGreenSub(sub7);

        //6天

        Integer add6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"+");
        Integer sub6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"-");
        double d6=getEndNum(add6,sub6);
        if(0!=d6){
            sharesDataProbRed.setProbSixPlateGreen(d6);
        }
        sharesDataProbRed.setProbSixPlateGreenAdd(add6);
        sharesDataProbRed.setProbSixPlateGreenSub(sub6);

        //5天
        Integer add5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(3)+"+");
        Integer sub5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(3)+"-");
        double d5=getEndNum(add5,sub5);
        if(0!=d5){
            sharesDataProbRed.setProbFivePlateGreen(d5);
        }
        sharesDataProbRed.setProbFivePlateGreenAdd(add5);
        sharesDataProbRed.setProbFivePlateGreenSub(sub5);

    }

    @Override
    public void getAfterPorbAll(SharesDataProbRed sharesDataProbRed) {
        String code = Constant.ALL;
        String zdfTrend = sharesDataProbRed.getZdfTrend().replaceAll("\\d+", "")+"-";

        //7天
        Integer add7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"+");
        Integer sub7 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(1)+"-");
        double d7=getEndNum(add7,sub7);
        if(0!=d7){
            sharesDataProbRed.setProbSevenAllGreen(d7);
        }
        sharesDataProbRed.setProbSevenAllGreenAdd(add7);
        sharesDataProbRed.setProbSevenAllGreenSub(sub7);


        //6天

        Integer add6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"+");
        Integer sub6 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(2)+"-");
        double d6=getEndNum(add6,sub6);
        if(0!=d6){
            sharesDataProbRed.setProbSixAllGreen(d6);
        }
        sharesDataProbRed.setProbSixAllGreenAdd(add6);
        sharesDataProbRed.setProbSixAllGreenSub(sub6);

        //5天
        Integer add5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(3)+"+");
        Integer sub5 =(Integer) redisTemplate.opsForValue().get(code + zdfTrend.substring(3)+"-");
        double d5=getEndNum(add5,sub5);
        if(0!=d5){
            sharesDataProbRed.setProbFiveAllGreen(d5);
        }
        sharesDataProbRed.setProbFiveAllGreenAdd(add5);
        sharesDataProbRed.setProbFiveAllGreenSub(sub5);
    }

    @Override
    public void getAfterZdfProbPlate(SharesDataProbRed sharesDataProbRed) {
        String zdfTrend = sharesDataProbRed.getZdfTrend();
        Map<String, Double> zdf5 = getZdfProbAllByRedis(sharesDataProbRed, zdfTrend.substring(4));
        Double p5 = zdf5.get(Constant.ALL);
        if(0!=p5){
            sharesDataProbRed.setZdfProbFivePlateGreen(p5);
        }

        Map<String, Double> zdf4 = getZdfProbAllByRedis(sharesDataProbRed, zdfTrend.substring(8));
        Double p4 = zdf4.get(Constant.ALL);
        if(0!=p4){
            sharesDataProbRed.setZdfProbFourPlateGreen(p4);
        }

        Map<String, Double> zdf3 = getZdfProbAllByRedis(sharesDataProbRed, zdfTrend.substring(10));
        Double p3 = zdf3.get(Constant.ALL);
        if(0!=p3){
            sharesDataProbRed.setZdfProbThreePlateGreen(p3);
        }
    }

    @Override
    public Page<SharesDataProbRed> getProbByTrend(SharesDataProbRed sharesDataProbRed) {

        Wrapper<SharesDataProbRed> wr =new EntityWrapper<>();
        wr.eq("time_str","2021-04-30");


        String orderName = sharesDataProbRed.getOrderName();
        String orderStr = sharesDataProbRed.getOrderStr();

        if(StringUtils.isEmpty(orderStr)&&StringUtils.isEmpty(orderName)){
            wr.orderBy(orderName,false);
        }

        Page<SharesDataProbRed> page =new Page<>(1,30);
        Page<SharesDataProbRed> sharesDataProbRedPage = this.selectPage(page, wr);
        return  sharesDataProbRedPage;
    }

    private double getEndNum(Integer add, Integer sub) {
        if(null!=add&&null!=sub){
            double v = add / (double) (sub + add);
            double zdf7 = new BigDecimal(v).setScale(2, BigDecimal.ROUND_UP).doubleValue();
            return zdf7;
        }else{
            if(null!=add&&null==sub){
                return  1;
            }else{
                return  0;
            }
        }
    }


    private Map<String,Double> getZdfProbAllByRedis(SharesDataProbRed sharesDataProb, String zdfTrend) {
        Map<String,Double> dMap=new HashMap<>();
        Map<String, Integer> map = (Map<String, Integer>)redisTemplate.opsForValue().get(sharesDataProb.getCode().substring(0,3)+zdfTrend);


        Integer add=0;
        Integer div=0;

        if(!CollectionUtils.isEmpty(map)){
            Iterator<String> iterator = map.keySet().iterator();
            while (iterator.hasNext()){
                String next = iterator.next();
                String nextIf = next.substring(next.length() - 2, next.length() - 1);
                Integer integer = map.get(next);
                if(nextIf.equals("+")){
                    add=add+integer;
                }else{
                    div=div+integer;
                }
            }
        }

        dMap.put("add",(double)add);
        dMap.put("div",(double)div);

        if(0!=add&&0!=div){
            double v = add / (double) (add + div);
            double zdf7 = new BigDecimal(v).setScale(2, BigDecimal.ROUND_UP).doubleValue();
            dMap.put(Constant.ALL,zdf7);
        }else{
            if(0!=add){
                dMap.put(Constant.ALL,1d);
            }else{
                dMap.put(Constant.ALL,0d);
            }

        }
        return  dMap;
    }
}
